home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Day Cry
/
Day Cry CD.bin
/
oh_towns
/
taropyon
/
splib
/
splib.lzh
/
PRG
/
LHX
/
HEADER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-08
|
9KB
|
445 lines
/***********************************************************
header.c -- handle headers
***********************************************************/
#define MSDOS
#define MYDOS 'M'
#include "lh386.h"
#include <stdio.h>
#include <io.h>
#include <dos.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include "lh.h"
#include "intrface.h"
#include "errmes.h"
#ifdef __HIGHC__
# pragma On(Align_labels);
# pragma On(Char_default_unsigned)
#endif
#define HDRwork (uchar *)(work + 0)
#define HDRsize (uchar *)(work + 0)
#define HDRwhole (uchar *)(work + 0)
#define HDRsum (uchar *)(work + 1)
#define HDRmethod (uchar *)(work + 2)
#define HDRpacked (uchar *)(work + 7)
#define HDRoriginal (uchar *)(work + 11)
#define HDRtime (uchar *)(work + 15)
#define HDRattr (uchar *)(work + 19)
#define HDRlevel (uchar *)(work + 20)
#define HDRfnlen (uchar *)(work + 21)
#define HDRfname (uchar *)(work + 22)
#define HDRdos (uchar *)(work + 23)
#define HDRextsize (uchar *)(work + 24)
struct head hpb;
char methodID[6] = "\0\0\0\0\0\0";
static ulong nextpos;
#ifdef MSDOS
#ifndef __HIGHC__
#define Convint(p) (*(int *)(p))
#else
#define Convint(p) (*(short *)(p))
#endif
#define Convlong(p) (*(long *)(p))
#else
#define Convint(p) (*(p) + ((unsigned)*((p) + 1) << 8))
#define Convlong(p) (Convint(p) + ((ulong)Convint((p) + 2) << 16))
#endif
#ifdef MSDOS
#ifndef __HIGHC__
#define Setint(p, q) (*(uint *)(p)=q)
#else
#define Setint(p, q) (*(ushort *)(p)=q)
#endif
#define Setlong(p, q) (*(ulong *)(p)=q)
#else
#define Setint(p, q) {uint a = q; (p)[0] = a; (p)[1] = a >> 8;}
#define Setlong(p, q) {ulong a = q; \
(p)[0] = a; (p)[1] = a >> 8; \
(p)[2] = a >> 16; (p)[3] = a >> 24;}
#define MAXNAMELEN 128
#endif
void inithdr(void)
{
long pos;
int c, err;
char *p;
pos = 0;
while ((c = getc(file1)) >= 0)
{
pos++;
if (c == '-')
{
getc(file1);
getc(file1);
getc(file1);
if (getc(file1) == '-')
{
nextpos = pos - 3;
p = gethdr(&err);
if (p)
{
free(p);
nextpos = pos - 3;
return;
}
}
fseek(file1, pos, SEEK_SET);
}
}
return;
}
/*******************************
calculate check-sum of header
*******************************/
static char calcsum(void *h)
{
char *p, *q, i;
p = (char *) h + 2;
q = p + *(uchar *) h;
for (i = 0; p < q; p++)
i += *p;
return i;
}
static void extheader(char *exthdr, int size)
{
uchar *p;
p = (uchar *) exthdr + 1;
switch (*exthdr)
{
case 0:
hpb.headcrc = Convint(p);
hpb.crcpos = (char *) p;
if (size > 5)
hpb.info = *(p + 2);
break;
case 1:
hpb.filename = (char *) p;
hpb.filenlen = size - 3;
break;
case 2:
hpb.pathname = (char *) p;
hpb.dirnlen = size - 3;
break;
case 0x40:
if (hpb.dos == MYDOS)
{
hpb.attr = Convint(p);
}
break;
}
}
#define readarc(a,b) fread(a, 1, b, file1)
char *gethdr(int *err)
/***
*err = 0 : normal end of header
= 1 : not a header
****/
{
char *p;
int namelen, extsize;
int i;
*err = 0;
hpb.crcpos = NULL;
memset(&hpb, 0, sizeof(struct head));
*HDRsize = 0;
fseek(file1, nextpos, SEEK_SET);
readarc(HDRwork, 21);
if (*HDRsize == 0)
return NULL;
hpb.headersize = (int) *HDRsize + 2;
strncpy((char *) hpb.method, (char *) HDRmethod, 5);
hpb.packed = hpb.skip = Convlong(HDRpacked);
hpb.original = Convlong(HDRoriginal);
hpb.level = *HDRlevel;
hpb.attr = *HDRattr;
hpb.dirnlen = 0;
switch (hpb.level)
{
case 0:
case 1:
hpb.dostime.u = Convlong(HDRtime);
hpb.utc = dos2unix(&hpb.dostime.s);
if (hpb.headersize < 22)
return NULL;
readarc(HDRwork + 21, hpb.headersize - 21);
if (calcsum(HDRwork) != *HDRsum)
{
if (*HDRwork == 0x1a)
return NULL;/* for LArc & XMODEM */
*err = 1;
return NULL;
}
namelen = *HDRfnlen;
hpb.filenlen = namelen;
hpb.filename = hpb.pathname = (void *) HDRfname;
i = hpb.headersize - namelen;
if (i >= 24)
{
hpb.filecrc = Convint(HDRfname + namelen);
} else
{
hpb.level = -1;
}
if (i >= 25)
{
hpb.dos = *(HDRfname + namelen + 2);
}
nextpos = ftell(file1) + hpb.skip;
if (hpb.level <= 0)
{
strncpy((char *) (hpb.pathname = e_malloc(namelen + 1)),
(char *) HDRfname, namelen);
hpb.pathname[namelen] = '\0';
hpb.filename = convdelim(hpb.pathname, DELIM);
return hpb.pathname;
}
p = (char *) HDRwork + *HDRsize;
while ((extsize = Convint(p)) != 0)
{
readarc(p + 2, extsize);
extheader(p + 2, extsize);
p += extsize;
}
i = p + 2 - (char *) HDRwork;
hpb.packed -= i - hpb.headersize;
hpb.headersize = i;
break;
case 2:
readarc(HDRwork + 21, (hpb.headersize = Convint(HDRwhole)) - 21);
hpb.utc = Convlong(HDRtime);
hpb.dos = *HDRdos;
p = (char *) HDRextsize;
while ((extsize = Convint(p)) != 0)
{
extheader(p + 2, extsize);
p += extsize;
}
hpb.filecrc = Convint(HDRfnlen);
nextpos = ftell(file1) + hpb.skip;
break;
default:
*err = 1;
return NULL;
}
if (hpb.crcpos)
{
Setint(hpb.crcpos, 0);
crc = 0;
if (calccrc(HDRwork, hpb.headersize) != hpb.headcrc)
{
*err = 1;
return NULL;
}
Setint(hpb.crcpos, hpb.headcrc);
}
namelen = hpb.dirnlen + hpb.filenlen;
p = e_malloc(namelen + 1);
hpb.pathname = strncpy(p, hpb.pathname, hpb.dirnlen);
hpb.filename = strncpy(p + hpb.dirnlen, hpb.filename, hpb.filenlen);
*(p + namelen) = '\0';
convdelim(hpb.pathname, DELIM);
return hpb.pathname;
}
void makehdr(void)
{
int namelen;
uchar *p, *q;
hpb.crcpos = NULL;
memcpy(HDRmethod, hpb.method, 5);
Setlong(HDRpacked, hpb.skip = hpb.packed);
Setlong(HDRoriginal, hpb.original);
*HDRattr = 0x20;
*HDRlevel = hpb.level;
q = (uchar *) hpb.filename;
if (hpb.level == 0)
q = (uchar *) hpb.pathname;
namelen = strlen((char *) q);
p = (uchar *) HDRfnlen;
if (hpb.level != 2)
{
#ifndef MSDOS
if (namelen > MAXNAMELEN)
{
*p++ = 0;
} else
#endif
{
*p++ = namelen;
strcpy((char *) p, (char *) q);
if (hpb.level == 0)
convdelim((char *) p, pathdelim);
p += namelen;
}
hpb.dostime.s = *unix2dos(hpb.utc);
Setlong(HDRtime, hpb.dostime.u);
} else
{
Setlong(HDRtime, hpb.utc);
}
p += 2; /* filecrc */
if (hpb.level == 0)
{
*HDRsize = (uchar *) p - HDRmethod;
hpb.headersize = (uchar *) p - HDRwork;
*HDRattr = hpb.attr;
*HDRsum = calcsum(HDRwork);
return;
}
*p = MYDOS;
p++;
*HDRsize = p - HDRwork;
/*
| filename header |
| 2 ext-header size |
|----------------------|
| 1 0x01 |
| ? filename |
|----------------------|
*/
if (hpb.level == 2
#ifndef MSDOS
|| namelen > MAXNAMELEN
#endif
)
{
hpb.filenlen = strlen(hpb.filename);
Setint(p, hpb.filenlen + 3);
p += 2;
*p++ = 1;
memcpy(p, hpb.filename, hpb.filenlen);
p += hpb.filenlen;
}
/*
| dirname header |
| 2 ext-header size |
|----------------------|
| 1 0x02 |
| ? dirname |
|----------------------|
*/
if (hpb.pathname != hpb.filename)
{
hpb.dirnlen = hpb.filename - hpb.pathname;
Setint(p, hpb.dirnlen + 3);
p += 2;
*p++ = 2;
convdelim(hpb.pathname, DELIM2);
memcpy(p, hpb.pathname, hpb.dirnlen);
p += hpb.dirnlen;
convdelim(hpb.pathname, DELIM);
}
#ifdef MSDOS
/*
| attribute header |
| 2 ext-header size |
|----------------------|
| 1 0x40 |
| 2 attribute |
|----------------------|
*/
if (hpb.attr != 0x20)
{
Setint(p, 5);
p += 2;
*p++ = 0x40; /* ext-header type */
Setint(p, hpb.attr);
p += 2;
}
#endif
/*
| common header |
| 2 ext-header size |
|----------------------|
| 1 0x00 |
| 2 header crc |
| ( 1 information ) |
|----------------------|
*/
if (p != HDRwor